// 引入axios插件
import axiosPlug from 'axios'
// 引入vuex
import Store from '@/store'
// 引入router，后面会有跳转
import router from '@/router'

// 创建axios实例
const axios = axiosPlug.create({
  // 设置url前缀
  baseURL: 'http://edufront.lagou.com'
})

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 设置请求头,判断是否登录，登录就带上请求头
  if (Store.state.user) config.headers.Authorization = Store.state.user.access_token || ''
  // 返回新的配置信息
  return config
}, function (error) {
  // 抛出错误
  return Promise.reject(error)
})

// 信号值，是否正在刷新token
let uploading = false
// 除刷新token的请求外，其他请求全部暂时存储起来
let ajax = []

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 响应成功什么都不做
  return response
}, async error => {
  // 如果有响应
  if (error.response) {
    // 判断返回状态码是否是401
    if (error.response.status === 401) {
      // 判断用户是否登录
      if (!Store.state.user) {
        // 用户未登录，直接带参数返回登录
        router.push({
          name: 'login',
          query: {
            path: router.currentRoute.fullPath
          }
        })
        return Promise.reject(error)
      }
      // 判断是否正在刷新token
      if (uploading) {
        // 正在刷新token将剩下的请求全部挂起保存起来
        return ajax.push(() => {
          axios(error.config)
        })
      }
      // 没刷新token则更改状态为刷新
      uploading = true
      // 尝试刷新token
      const { data } = await axios({
        method: 'post',
        url: '/front/user/refresh_token',
        data: new window.URLSearchParams({
          refreshtoken: Store.state.user.refresh_token
        }).toString()
      })
      if (data.state !== 1) {
        // 刷新token失败，清空用户信息
        Store.commit('setUser', null)
        // 带参数返回登录
        router.push({
          name: 'login',
          query: {
            path: router.currentRoute.fullPath
          }
        })
        return Promise.reject(error)
      }
      // 刷新token成功
      // 保存新的登录信息
      Store.commit('setUser', data.content)
      // 将之前挂起的请求重新发送
      ajax.forEach(fn => fn())
      // 清空请求
      ajax = []
      // 修改状态为未刷新
      uploading = false
      // 最后重新发送本次请求
      return axios(error.config)
    }
  }
  return Promise.reject(error)
})

// 导出实例
export default axios
